 /** 
 * @addtogroup nmea
 * nmea
 * @brief NMEA库通用类型定义头文件
 * @{
 */

/**
 * @file nmea_types.h
 * @brief NMEA库通用类型定义头文件
 * 
 * @author lzl(lzl@hopechart.com)
 * @copyright 杭州鸿泉物联网技术股份有限公司
 * 
 * @par 修订日志
 * <table>
 * <tr><th>Date         <th>Version <th> Author                         <th> Descripton
 * <tr><td>2019-09-19   <td>1.1     <td> liuzl                          <td> 建立初始版本
 * <tr><td>2020-12-01   <td>1.2     <td> Akee(ysk@hopechart.com,尤胜坤) <td> 头文件注释增加
 * </table>
 * 
 */
#ifndef _HUBS_LIB_NMEA_TYPES_H_
#define _HUBS_LIB_NMEA_TYPES_H_

#include <time.h>

/**
 * Talker标识枚举
 * 
 * 取自地址字段头两个字符,比如$GPRMC中的GP为Talker标识
 */
enum TNmeaTalkerTag 
{
    kNmeaTalkerNone,                            ///< ??-初始化值
    kNmeaTalkerUnknown,                         ///< ??-未知的
    kNmeaTalkerGnss,                            ///< GN-全球导航卫星系统
    kNmeaTalkerGps,                             ///< GP-全球定位系统
    kNmeaTalkerBeidou,                          ///< BD-北斗
    kNmeaTalkerGlonass,                         ///< GL-GLONASS
    kNmeaTalkerGalileo,                         ///< GA-GALILEO
    kNmeaTalkerQzss,                            ///< QZ-qzss
};
typedef enum TNmeaTalkerTag TNmeaTalker;

enum TNmeaSentenceTag 
{
    kNmeaSentenceNone,
    kNmeaSentenceUnknown,
    kNmeaSentenceRmc,       ///< rmc语句
    kNmeaSentenceGga,       ///< gga语句
    kNmeaSentenceGsa,       ///< gsa语句
    kNmeaSentenceGsv,       ///< gsv语句
    kNmeaSentenceGll,       ///< gll语句
    kNmeaSentenceDhv = 1000,       ///< DHV语句，北斗协议---非通用NMEA语句，均添加到1000以后
    kNmeaSentenceTxt = 1001,       ///< GPTXT语句  中科微AGNSS使用
};
typedef enum TNmeaSentenceTag TNmeaSentence;
#define NMEA_SENTENCE(a,b,c) ((TNmeaSentence)((a<<16)|(b<<8)|c))

/*
 * 操作模式
 */
enum TNmeaOperateModeTag 
{
    kNmeaOperateModeNone,
    kNmeaOperateModeUnknown,    ///< 未知
    kNmeaOperateModeAutomatic,  ///< 手动，强制用于2D或3D模式
    kNmeaOperateModeManual,     ///< 自动，允许2D/3D自动切换
};
typedef enum TNmeaOperateModeTag TNmeaOperateMode;

/*
 * 选用模式
 */
enum TNmeaFixModeTag 
{
    kNmeaFixModeNone,
    kNmeaFixModeUnknown,        ///< 未知
    kNmeaFixModeNotAvailable,   ///< 定位不可用或无效
    kNmeaFixMode2D,             ///< 2D定位
    kNmeaFixMode3D,             ///< 3D定位
};
typedef enum TNmeaFixModeTag TNmeaFixMode;

/**
 * 地址字段结构
 *  
 * 包含语句对应的地址标识，NMEA字符串中由$或者!打头的5个字符组成,比如$GPRMC：
 * - GP为TalkerID
 * - RMC为语句标识
 */
struct TNmeaAddrFieldTag 
{
    TNmeaTalker talker;                          ///< TalkerID
    TNmeaSentence sentence;                      ///< 语句标识
};
typedef struct TNmeaAddrFieldTag TNmeaAddrField;

/**
 * 数据状态枚举
 */
enum TNmeaDataStatusTag 
{
    kNmeaDataStatusNone,                        ///< 未知
    kNmeaDataStatusValid,                       ///< 有效
    kNmeaDataStatusInvalid,                     ///< 无效
};
typedef enum TNmeaDataStatusTag TNmeaDataStatus;

/**
 * 定位系统模式
 *
 */
enum TNmeaPositionSysModeTag 
{
    kNmeaPositionSysModeNone,                   ///< ( )空的
    kNmeaPositionSysModeUnknown,                ///< (?)未知的
    kNmeaPositionSysModeAutonomous,             ///< (A)自主定位
    kNmeaPositionSysModeDifferential,           ///< (D)差分定位
    kNmeaPositionSysModeEstimated,              ///< (E)估算
    kNmeaPositionSysModeManual,                 ///< (M)手动
    kNmeaPositionSysModeSimulator,              ///< (S)模拟
    kNmeaPositionSysModeNotValid,               ///< (N)数据不可用
};
typedef enum TNmeaPositionSysModeTag TNmeaPositionSysMode;

/**
 * RMC结构中字段有效性掩码
 * 
 * 作用于TNmeaRmc结构的flag字段，flag响应位为1标识该字段值有效
 */
/**@{*/
#define NMEA_RMC_HAS_STATUS         (0x1)       ///< RMC结构中状态是否有效，定位有效状态
#define NMEA_RMC_HAS_TIMESTAMP      (0x2)       ///< RMC结构中时间是否有效，时间戳
#define NMEA_RMC_HAS_LAT_LONG       (0x4)       ///< RMC结构中经纬是否有效，经纬度
#define NMEA_RMC_HAS_SPEED          (0x8)       ///< RMC结构中速度是否有效，速度
#define NMEA_RMC_HAS_BEARING        (0x10)      ///< RMC结构中方向是否有效，对地航向
#define NMEA_RMC_HAS_MODE           (0x20)      ///< RMC结构中模式是否有效，位置系统模式
/**@}*/

/**
 * 推荐最小GNSS数据
 *
 * 包含了时间、日期、航向、车速
 */
struct TNmeaRmcTag 
{
    int flags;                                  ///< 字段有效标志(由NMEA_RMC_HAS_组成)
    TNmeaDataStatus data_status;                ///< 定位有效状态
    TNmeaPositionSysMode mode;                   ///< 定位模式
    time_t time_utc;                            ///< UTC时间
    int latitude;                               ///< 纬度(正北负南)
    int longitude;                              ///< 经度(正东负西)
    int speed;                                  ///< 车速(单位:m/h)
    int bearing;                                ///< 方位(单位:0.01度)
    int time_ms;                                ///< UTC毫秒时间，单位毫秒
};

typedef struct TNmeaRmcTag TNmeaRmc;

/**
 * 质量指示器
 */
enum TNmeaQualityIndTag 
{
    kNmeaQualityIndNone,
    kNmeaQualityIndUnknown,
    kNmeaQualityIndNotAvailable,                ///< 不可用
    kNmeaQualityIndGpsSpsMode,                  ///< GPS标准位置服务模式,定位有效
    kNmeaQualityIndDgpsSpsMode,                 ///< DGPS标准位置服务模式,定位有效
    kNmeaQualityIndGpsPpsMode,                  ///< GPS精确位置服务模式,定位有效
    kNmeaQualityIndRtkMode,                     ///< 实时动态差分模式,定位有效
    kNmeaQualityIndFloatRtkMode,                ///< 实时动态差分模式,定位有效
    kNmeaQualityIndEstimatedMode,               ///< 推算模式
    kNmeaQualityIndManualInputMode,             ///< 手动输入模式
    kNmeaQualityIndSimulatorMode,               ///< 仿真模式
};
typedef enum TNmeaQualityIndTag TNmeaQualityInd;

/**
 * GGA结构中字段有效性掩码
 * 
 * 作用于TNmeaGga结构的flag字段，flag响应位为1标识该字段值有效
 */
/**@{*/
#define NMEA_GGA_HAS_QIND           (0x1)       ///< GGA结构中质量指示是否有效
#define NMEA_GGA_HAS_TIMESTAMP      (0x2)       ///< GGA结构中时间是否有效
#define NMEA_GGA_HAS_LAT_LONG       (0x4)       ///< GGA结构中经纬是否有效
#define NMEA_GGA_HAS_SV_INUSED      (0x8)       ///< GGA结构中卫星数是否有效
#define NMEA_GGA_HAS_BEARING        (0x10)      ///< GGA结构中水平精度是否有效
#define NMEA_GGA_HAS_HDOP           (0x20)      ///< GGA结构中模式是否有效
#define NMEA_GGA_HAS_ALTITUDE       (0x40)      ///< GGA结构中海拔是否有效
#define NMEA_GGA_HAS_GEOIDAL_HEIGHT (0x80)      ///< GGA结构中大地水准面高程是否有效
#define NMEA_GGA_HAS_DGPS_AGE       (0x100)     ///< GGA结构中差分数据时间是否有效
#define NMEA_GGA_HAS_STATION_ID     (0x200)     ///< GGA结构中差分站是否有效
/**@}*/

/**
 * 全球定位系统数据
 */
struct TNmeaGgaTag 
{
    int flags;                                  ///< 字段有效标志(由NMEA_GGA_HAS_组成)
    time_t utc_sec;                             ///< UTC时间(秒)
    TNmeaQualityInd qind;                       ///< 质量指示器
    int latitude;                               ///< 纬度(正北负南)
    int longitude;                              ///< 经度(正东负西)
    int sv_in_used;                             ///< 使用卫星数
    int hdop;                                   ///< 水平精度(100倍)
    int altitude;                               ///< 海拔(厘米)
    int geoidal_height;                         ///< 大地水准面高程(厘米）
    int dgps_data_age;                          ///< 差分数据时间（上次差分数据过去的秒数）
    int station_id;                             ///< 差分参考站ID
    int time_ms;                                ///< UTC毫秒时间，单位毫秒
};
typedef struct TNmeaGgaTag TNmeaGga;

/**
 * GGA结构中字段有效性掩码
 * 
 * 作用于TNmeaGga结构的flag字段，flag响应位为1标识该字段值有效
 */
/**@{*/
#define NMEA_GSA_HAS_MODE           (0x1)       ///< GSA结构中mode字段是否有效
#define NMEA_GSA_HAS_FIXMODE        (0x2)       ///< GSA结构中fix_mode字段是否有效
#define NMEA_GSA_HAS_PDOP           (0x4)       ///< GSA结构中pdop字段是否有效
#define NMEA_GSA_HAS_VDOP           (0x8)       ///< GSA结构中vdop字段是否有效
#define NMEA_GSA_HAS_HDOP           (0x10)      ///< GSA结构中hdop字段是否有效
/**@}*/

struct TNmeaGsaTag 
{
    int flags;                                  ///< 字段有效标志(由NMEA_GSA_HAS_组成)
    TNmeaOperateMode mode;                      ///< 操作模式
    TNmeaFixMode fix_mode;                      ///< 定位模式
    int pdop;                                   ///< 位置精度(放大100倍)
    int vdop;                                   ///< 垂直精度(放大100倍)
    int hdop;                                   ///< 水平精度(放大100倍)
    int sv_used_num;                            ///< 使用卫星数
    int sv_used_in_fix[32];                     ///< 使用卫星编号(PRN)
};
typedef struct TNmeaGsaTag TNmeaGsa;

/**
 * 卫星列表项
 */
struct TNmeaSvTag 
{
    int prn;                                    ///< 卫星编号
    int elevation;                              ///< 仰角(0~90度)
    int azimuth;                                ///< 方位角(0~359度)
    int snr;                                    ///< 信噪比
};
typedef struct TNmeaSvTag TNmeaSv;

/**
 * GSV结构中字段有效性掩码
 * 
 * 作用于TNmeaGsv结构的flag字段，flag响应位为1标识该字段值有效
 */
/**@{*/
#define NMEA_GSV_HAS_TOTAL           (0x1)       ///< GSV结构中total字段是否有效
#define NMEA_GSV_HAS_INDEX           (0x2)       ///< GSV结构中index字段是否有效
#define NMEA_GSV_HAS_IN_VIEW_NUM     (0x4)       ///< GSV结构中sv_num_in_view字段是否有效
#define NMEA_GSV_HAS_SIGNAL_ID       (0x8)       ///< GSV结构中signal_id字段是否有效
/**@}*/

/**
 * 可视卫星状态
 */
struct TNmeaGsvTag 
{
    int flags;                                  ///< 字段有效标志(由NMEA_GSV_HAS_组成)
    time_t time_utc;                            ///< UTC时间
    int total;                                  ///< 总颗数,从1开始
    int index;                                  ///< 当前索引号,从0开始
    int sv_num_in_view;                         ///< 可见卫星总数
    int sv_num_in_msg;                          ///< 当前消息包的卫星个数,从sv_list获取
    int signal_id;                              ///< 卫星信号id，大于0表示有效，等于0为无效
    TNmeaSv sv_list[4];                         ///< 卫星列表(每次最多4个)
};

typedef struct TNmeaGsvTag TNmeaGsv;

#endif//_HUBS_LIB_NMEA_TYPES_H_

/**
 * @} 
 */
